package net.zoneland.zrdp.biz.common;


import net.zoneland.zrdp.biz.enums.CompanyEnum;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统业务相关工具类.
 * 1、OA组织DN的中文名称转换
 * 2、不为空属性对象的复制
 * 3、对字符串的一系列函数
 * @version v1.0
 */
public final class CommonUtils {

    /** 未知的. */
    public static final String UNKNOWN = "unknown";
    /** 组织前缀. */
    public static final String ORG_PRIEX = "OU=";

    private CommonUtils() {
    }

    /**
     * 获取组织全路径以-分隔.
     * 如：OU=兰德,OU=信息技术部,OU=合作伙伴,O=zmcc 显示为 省公司-合作伙伴-信息技术部-兰德
     * @author Pbody
     * @param departmentDn 部门dn
     * @return java.lang.String
     **/
    public static String getFullDeptName(final String departmentDn) {
        final StringBuilder deptNameBuilder = new StringBuilder();
        final String[] deptArray = departmentDn.split(Constants.SPLIT_COMMA);
        Optional.of(deptArray).filter(ArrayUtils::isNotEmpty).ifPresent(array -> {
            // 1、处理公司名称
            final String[] deptArr  = getDeptArr(array);
            //2、解析出dn中的OU、中文名称并放入map并标记序号
            final Map<Integer, String> nameMap = new HashMap<>();
            Arrays.stream(deptArr).forEach(arr ->
                Optional.of(Arrays.asList(arr.split(Constants.SPLIT_EQUAL))).orElseGet(() -> Collections.singletonList(arr)
                ).stream().filter(str -> !Constants.ZMCC_OU.equals(str)).forEach(str -> nameMap.put(nameMap.size() + 1, str))
            );
            //3、以按map中key的倒序并以-分隔显示
            deptNameBuilder.append(nameMap.entrySet().stream().sorted(Map.Entry.<Integer, String>comparingByKey().reversed())
                .map(Map.Entry::getValue).collect(Collectors.joining(Constants.SPLIT_DASH)));
        });
        return deptNameBuilder.toString();
    }

    /**
    * 获取部门名称的数组.
    * @author pbody
    * @param deptArray 部门信息数组
    * @return java.lang.String[]
    **/
    private static String[] getDeptArr(final String[] deptArray) {
        String[] deptArr = deptArray.clone();
        int arrLength = deptArr.length;
        if (arrLength > 1) {
            // 根据公司dn获取名称
            final String companyName = Optional.ofNullable(EnumUtils.getByValue(CompanyEnum.class, StringUtils.
                join(new String[]{deptArr[arrLength - Constants.NUMBER_TWO], Constants.SPLIT_COMMA, deptArr[arrLength - 1]})))
                .map(CompanyEnum::getName).orElse(null);
            if (StringUtils.isBlank(companyName)) {
                deptArr[arrLength - 1] = Constants.INNER_PROVINCE_ONAME;
                return deptArr;
            }
            // 地市分公司获取后数组长度要减一
            final String[] newArr = new String[arrLength - 1];
            deptArr[arrLength - Constants.NUMBER_TWO] = companyName;
            for (int i = 0; i < arrLength; i++) {
                if (i != arrLength - 1) {
                    newArr[i] = deptArr[i];
                }
            }
            deptArr = newArr;
        }
        return deptArr;
    }

    /**
     * 获取对象中为空的属性集合.
     * @author Pbody
     * @param source 源Bean对象
     * @return java.lang.String[]
     **/
    public static String[] getNullPropertyNames(final Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        final java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        final Set<String> emptyNames = new HashSet<>();
        for (java.beans.PropertyDescriptor pd : pds) {
            final Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        return emptyNames.toArray(new String[0]);
    }

    /**
     * 对象复制工具类：对象属性为空的不复制.
     * @author Pbody
     * @param src 原始数据对象
     * @param target 操作的目标数据对象
     **/
    public static void copyProperties(final Object src, final Object target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }

    /**
     * 这不是普通的字符串包含，判断指定的字符串在数组中是否存在.
     * @param src 以逗号分隔的字符数组
     * @param target 要判断的字符串
     * @return boolean
     */
    public static boolean containString(final String src, final String target) {
        if (StringUtils.isNotBlank(src)) {
            String[] srcArr = src.split(Constants.SPLIT_COMMA);
            for (String item : srcArr) {
                if (item.equals(target)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 方正|cjfz,胡欧|huou,获取账号.
     * @param src 要判断的字符串
     * @param index 1获取姓名，2获取账号
     * @return String
     */
    public static String getNameFromFix(final String src, final int index) {
        if (StringUtils.isNotBlank(src)) {
            final List<String> nameList = new ArrayList<>();
            Arrays.stream(src.split(Constants.SPLIT_COMMA)).forEach(obj -> {
                final String[] arrObj = obj.split("\\|");
                if (arrObj.length > 1 && Constants.NUMBER_TWO == index) {
                    nameList.add(arrObj[1]);
                } else {
                    nameList.add(arrObj[0]);
                }
            });
            return StringUtils.join(nameList, Constants.SPLIT_COMMA);
        }
        return null;
    }

    /**
     * 获取登陆者ip.
     * @author YTG
     * @param request 请求
     * @return java.lang.String
     **/
    public static String getIpAddr(final HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        if (ip.split(Constants.SPLIT_COMMA).length > 1) {
            ip = ip.split(Constants.SPLIT_COMMA)[0];
        }
        return ip;
    }

    /**
     * 根据组织dn获取一级部门名称
     * @author helu
     * @param orgDn  部门dn
     * @return java.lang.String
     **/
    public static String getTopDeptNameByOrgId(final String orgDn){
        final String companyDn = getCompanyDnByDeptDn(orgDn);
        return StringUtils.replace(StringUtils.substringAfterLast(StringUtils.substringBefore(orgDn,
            companyDn), ORG_PRIEX), Constants.SPLIT_COMMA, Strings.EMPTY);
    }

    /**
     * 获取一级部门DN.
     * @author helu
     * @param deptDn 部门.
     * @return java.lang.String
     **/
    public static String getTopDeptDn(final String deptDn) {
        final String companyDn = getCompanyDnByDeptDn(deptDn);
        final String orgName = StringUtils.substringAfterLast(StringUtils.substringBefore(deptDn,
            companyDn), ORG_PRIEX);
        return StringUtils.isNotBlank(orgName) ?
            ORG_PRIEX + orgName + companyDn : orgName + companyDn;
    }

     /**
     * 根据部门Dn获取公司DN
     * @author helu
     * @param deptDn 部门dn
     * @return java.lang.String
     **/
    public static String getCompanyDnByDeptDn(final String deptDn) {
        return Optional.ofNullable(deptDn)
            .filter(StringUtils::isNotBlank)
            .map(dept -> StringUtils.split(deptDn, Constants.SPLIT_COMMA))
            .filter(deptArray -> deptArray.length >= 2)
            .map(deptArray -> {
                //截取后两位作为公司DN
                final int length = deptArray.length;
                return deptArray[length - 2] + Constants.SPLIT_COMMA + deptArray[length - 1];
            })
            .map(company -> EnumUtils.getByValue(CompanyEnum.class, company))
            .map(CompanyEnum::getValue)
            .orElse(Constants.ORG_TOPORG_DN);
    }
}
